﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.IO;
using System.Linq;
using Microsoft.Win32;

namespace XiaLastorm.Sharpshooter.Client
{
	/// <summary>
	/// ChatWindow.xaml 的交互逻辑
	/// </summary>
	public partial class ChatWindow : Window
	{
		/// <summary>
		/// 获取聊天对象
		/// </summary>
		public User ChatTo { get; private set; }
		/// <summary>
		/// 生成 <see cref="ChatWindow"/> class 的新实例。
		/// </summary>
		/// <param name="chatTo">聊天对象</param>
		public ChatWindow(User chatTo)
		{
			ChatTo = chatTo;

			this.InitializeComponent();

			// 在此点之下插入创建对象所需的代码。
			BtnSend.Click += delegate
			{
				Chat();
			};
			RtbInput.KeyDown += (sender, e) =>
			{
				if (e.Key == Key.Enter && (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)))
				{
					Chat();
				}
			};

			double defaultFontSize = RtbInput.FontSize;
			bool fontSizeChangedManually = true;

			//输入框选择的文本改变时应对相应的控件做改变
			RtbInput.SelectionChanged += (sender, e) =>
				{
					CbFontFamily.SelectedItem = GetFontName(RtbInput.Selection.GetPropertyValue(TextElement.FontFamilyProperty) as FontFamily);
					object size = RtbInput.Selection.GetPropertyValue(TextElement.FontSizeProperty);
					fontSizeChangedManually = false;
					SldFontSize.Value = size == DependencyProperty.UnsetValue ? defaultFontSize : (double)size;
					fontSizeChangedManually = true;
				};

			//初始化字体
			var fontFamilies = Fonts.SystemFontFamilies;
			List<string> names = new List<string>();
			string selectedName = null;
			foreach (var fontFamily in fontFamilies)
			{
				string name = GetFontName(fontFamily);
				names.Add(name);
				if (name == GetFontName(RtbInput.FontFamily))
					selectedName = name;
			}
			names.Sort();
			CbFontFamily.ItemsSource = names;
			CbFontFamily.SelectedItem = selectedName;
			CbFontFamily.SelectionChanged += (sender, e) =>
				{
					if (e.AddedItems.Count > 0)
					{
						RtbInput.Selection.ApplyPropertyValue(TextElement.FontFamilyProperty, new FontFamily(e.AddedItems[0] as string));
					}
				};

			//初始化字号
			SldFontSize.Value = defaultFontSize;
			SldFontSize.ValueChanged += (sender, e) =>
			{
				if (fontSizeChangedManually)
				{
					RtbInput.Selection.ApplyPropertyValue(TextElement.FontSizeProperty, e.NewValue);
				}
			};

			//初始化插入图片
			BtnInsertPicture.Click += delegate
			{
				OpenFileDialog dialog = new OpenFileDialog();
				if (dialog.ShowDialog(this) == true)
				{
					InsertPicture(dialog.FileName);
				}
			};

			//初始化颜色
			ClPicker.SelectedColorChanged += new RoutedPropertyChangedEventHandler<Color>((sender, e) =>
			{
				RtbInput.Selection.ApplyPropertyValue(TextElement.ForegroundProperty, new SolidColorBrush(e.NewValue));
			});
		}

		/// <summary>
		/// 获取字体名称（简体中文字体返回中文名称）
		/// </summary>
		/// <param name="fontFamily">字体</param>
		/// <returns>字体名称</returns>
		public static string GetFontName(FontFamily fontFamily)
		{
			if (fontFamily == null) return null;
			if (fontFamily.FamilyNames.ContainsKey(System.Windows.Markup.XmlLanguage.GetLanguage("zh-cn")))
			{
				return fontFamily.FamilyNames[System.Windows.Markup.XmlLanguage.GetLanguage("zh-cn")];
			}
			return fontFamily.FamilyNames.First().Value;
		}

		/// <summary>
		/// 发送聊天内容
		/// </summary>
		/// <param name="content">聊天内容</param>
		public void Chat()
		{
			Client.AppClient.Chat(ChatTo, InputToXaml());
			RtbInput.Document = new FlowDocument();
		}

		/// <summary>
		/// 添加聊天记录
		/// </summary>
		/// <param name="chatLog">聊天记录</param>
		public void AddChatLog(ChatLog chatLog)
		{
			Run header = new Run(string.Format("{0} {1}\n", chatLog.From, chatLog.Time));
			header.FontWeight = FontWeights.UltraBlack;
			if (chatLog.From == Client.AppClient.User)
			{
				header.Foreground = new SolidColorBrush(Colors.Green);
			}
			else
			{
				header.Foreground = new SolidColorBrush(Colors.Blue);
			}

			if (RtbChatLog.Document.Blocks.LastBlock as Paragraph == null)
			{
				RtbChatLog.Document.Blocks.Clear();
				RtbChatLog.Document.Blocks.Add(new Paragraph());
			}
			(RtbChatLog.Document.Blocks.LastBlock as Paragraph).Inlines.Add(header);
			AddXamlToChatLog(chatLog.Content);
			Dispatcher.BeginInvoke(new Action(() =>
				{
					RtbChatLog.ScrollToEnd();
				}));
		}

		/// <summary>
		/// 将输入框中的内容转换为XAML
		/// </summary>
		/// <returns>XAML</returns>
		public byte[] InputToXaml()
		{
			using (MemoryStream stream = new MemoryStream())
			{
				TextRange range = new TextRange(RtbInput.Document.ContentStart, RtbInput.Document.ContentEnd);
				range.Save(stream, DataFormats.XamlPackage);
				stream.Seek(0, SeekOrigin.Begin);
				byte[] xaml = new byte[stream.Length];
				stream.Read(xaml, 0, xaml.Length);
				return xaml;
			}
		}

		/// <summary>
		/// 将XAML添加到聊天记录框中
		/// </summary>
		/// <param name="xaml">XAML</param>
		public void AddXamlToChatLog(byte[] xaml)
		{
			using (MemoryStream stream = new MemoryStream())
			{
				stream.Write(xaml, 0, xaml.Length);
				stream.Seek(0, SeekOrigin.Begin);
				TextRange range = new TextRange(RtbChatLog.Document.ContentEnd, RtbChatLog.Document.ContentEnd);
				range.Load(stream, DataFormats.XamlPackage);
			}
		}

		/// <summary>
		/// 在当前位置插入一张图片
		/// </summary>
		/// <param name="filename">图片文件名</param>
		public void InsertPicture(string filename)
		{
			try
			{
				Image picture = new Image();
				picture.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
				picture.VerticalAlignment = System.Windows.VerticalAlignment.Center;
				picture.Source = new BitmapImage(new Uri(filename, UriKind.Absolute));
				picture.Stretch = Stretch.None;

				EditingCommands.Delete.Execute(null, RtbInput);
				InlineUIContainer inline = new InlineUIContainer(picture, RtbInput.CaretPosition);
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}

		private void Button_Click(object sender, RoutedEventArgs e)
		{
			this.Close();
		}

		private void Button_Click_2(object sender, RoutedEventArgs e)
		{
			this.WindowState = System.Windows.WindowState.Minimized;
		}

		private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
		{
			if (e.Source is ColorPickerControl.ColorPicker)
				return;
			this.DragMove();
		}
	}
}